package me.zhengjie.server.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import me.zhengjie.controller.InboundController;
import me.zhengjie.dao.*;
import me.zhengjie.dao.dto.FreezeTaskRecordQueryCriteria;
import me.zhengjie.dao.dto.WareNestQueryCriteria;
import me.zhengjie.enums.ConstantStatus;
import me.zhengjie.enums.InboundStatusEnum;
import me.zhengjie.enums.PriorityEnum;
import me.zhengjie.mapper.FreezeMapper;
import me.zhengjie.mapper.WareNestMapper;
import me.zhengjie.network.WcsNetworkRequest;
import me.zhengjie.server.*;
import me.zhengjie.utils.*;
import me.zhengjie.vo.Inbound.MesMaterialVo;
import me.zhengjie.vo.OutBoundTaskToWcsVo;
import me.zhengjie.vo.freeze.FreezeVo;
import me.zhengjie.vo.merge.AgainBindVo;
import me.zhengjie.vo.Result;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import java.sql.Timestamp;
import java.util.*;

@Service
@RequiredArgsConstructor
public class FreezeServiceImpl extends ServiceImpl<FreezeMapper, FreezeDao> implements FreezeService {

    private static final Logger freezeLog = LoggerFactory.getLogger("freeze");

    private final MaterialService materialService;

    private final StoreLocalService storeLocalService;

    private final StoreOutsideService storeOutsideService;

    private final FreezeTaskRecordService freezeTaskRecordService;

    private final TransactionTemplate transactionTemplate;

    private final WareNestMapper wareNestMapper;

    private final ContainerService containerService;

    private final FreezeMapper freezeMapper;


    @Override
    public FreezeDao findDataByCode(String containerCode) {
        LambdaQueryWrapper<FreezeDao> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FreezeDao::getContainerCode, containerCode);
        return baseMapper.selectOne(wrapper);
    }


    @Override
    public List<FreezeDao> findDataList(FreezeDao freezeDao) {
        LambdaQueryWrapper<FreezeDao> wrapper = new LambdaQueryWrapper<>();
        if (freezeDao.getTaskId() != null) {
            wrapper.eq(FreezeDao::getTaskId, freezeDao.getTaskId());
        }
        if (freezeDao.getContainerCode() != null) {
            wrapper.eq(FreezeDao::getContainerCode, freezeDao.getContainerCode());
        }
        if (freezeDao.getStatus() != null) {
            wrapper.eq(FreezeDao::getStatus, freezeDao.getStatus());
        }
        return baseMapper.selectList(wrapper);
    }

    @Override
    public void updateDataByCode(FreezeDao freeDao) {
        LambdaUpdateWrapper<FreezeDao> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(FreezeDao::getContainerCode, freeDao.getContainerCode());
        baseMapper.update(freeDao, wrapper);
    }


    @Transactional(rollbackFor = Exception.class)
    public void deleteByContainerCode(String containerCode) {
        LambdaQueryWrapper<FreezeDao> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FreezeDao::getContainerCode, containerCode);
        baseMapper.delete(wrapper);
    }


    @Override
    public PageResult<WareNestDao> findWareMaterial(WareNestQueryCriteria criteria) {
        Page<WareNestDao> page = new Page<>(criteria.getPage(), criteria.getSize());
        return PageUtil.toPage(wareNestMapper.findAll(criteria, page));
    }


    @Override
    public PageResult<FreezeDao> findFreezeTaskList(FreezeTaskRecordQueryCriteria criteria) {
        Page<FreezeDao> page = new Page<>(criteria.getPage(), criteria.getSize());
        IPage<FreezeDao> freezeTaskList = freezeMapper.findFreezeTaskList(criteria, page);
        return PageUtil.toPage(freezeTaskList.getRecords(), freezeTaskList.getTotal());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> freeze(FreezeVo freezeVo) {
        List<String> itemBarCodeList = freezeVo.getItemBarCodeList();
        String freezeName = freezeVo.getFreezeName();
        String workIp = freezeVo.getWorkIp();

        Boolean confirm = freezeVo.getIsConfirm();
        String disableDes = freezeVo.getDisableDes();
        String disableNotes = freezeVo.getDisableNotes();
        if (itemBarCodeList.isEmpty()) {
            return Result.error("物料信息为空！");
        }

        if (freezeName == null || freezeName.isEmpty()) {
            return Result.error("冻结名称为空！");
        }
        if (workIp == null || workIp.isEmpty()) {
            return Result.error("工位为空！");
        }

        if (disableDes == null || disableDes.isEmpty()) {
            return Result.error("冻结描述为空！");
        }
        if (disableNotes == null || disableNotes.isEmpty()) {
            return Result.error("冻结备注为空！");
        }
        if (confirm == null) {
            return Result.error("是否确认为空！");
        }

        List<MaterialDao> MaterialList = materialService.findDataList(itemBarCodeList);
        if (MaterialList.isEmpty()) {
            return Result.error("物料信息不存在！");
        }

        // 获取每个载具对应的物料信息
        HashMap<String, List<MaterialDao>> freezeMap = new HashMap<>();
        handleMaterialList(MaterialList, freezeMap);

        for (Map.Entry<String, List<MaterialDao>> entry : freezeMap.entrySet()) {
            String containerCode = entry.getKey();
            // 根据载具编码获取要物料信息
            List<MaterialDao> materialList = materialService
                    .findDataDao(new MaterialDao().setContainerCode(containerCode));            HashSet<Object> hashSet = new HashSet<>();
            for (MaterialDao materialDao : materialList) {
                Integer disable = materialDao.getDisable() == null || materialDao.getDisable() == 0 ? 0 : 1;
                hashSet.add(disable);
                if (hashSet.size() > 1) {
                    return Result.error("该载具上存在不同状态物料，请先处理！");
                }
            }
        }

        String taskId = String.valueOf(SnowIdUtil.nextId());
        Timestamp freezeDate = new Timestamp(new Date().getTime());
        int status = -1; // 1 拆箱操作 2 存在混箱，拆箱确认
        // 确认冻结信息返回
        List<Map<String, String>> confirmList = new ArrayList<>();

        // 冻结任务信息
        List<FreezeDao> freezeDaoList = new ArrayList<>();
        // 物料冻结信息
        List<MaterialDao> materialResultList = new ArrayList<>();

        // List<String> storeIdList = new ArrayList<>();
        for (Map.Entry<String, List<MaterialDao>> entry : freezeMap.entrySet()) {
            // 获取需要冻结物料信息
            List<MaterialDao> materialDaoList = entry.getValue();
            // 获取载具上对应的物料信息表
            String containerCode = entry.getKey();
            boolean isExistSemiProduct = false;

            for (MaterialDao materialDao : materialDaoList) {
                if (materialDao.getMaterialCategory().equals("半成品")) {
                    isExistSemiProduct = true;
                    break;
                }
            }
            // 根据载具编码获取要物料信息
            List<MaterialDao> materialList = materialService
                    .findDataDao(new MaterialDao().setContainerCode(containerCode));

            // 存在半成品必须该载具上物料全部出库
            if (isExistSemiProduct && materialList.size() != materialDaoList.size()) {
                return Result.error("半成品必须该载具上物料全部出库！");
            }
            // 存在混箱/托需要拆箱/托操作
            if (!isExistSemiProduct && !confirm && materialList.size() != materialDaoList.size()) {
                Map<String, String> confirmMap = new HashMap<>();
                confirmMap.put("containerCode", containerCode);
                StringBuilder itemList = new StringBuilder();
                for (MaterialDao materialDao : materialDaoList) {
                    itemList.append(materialDao.getItemBarCode()).append(",");
                }
                String substring = itemList.substring(0, itemList.length() - 1);
                confirmMap.put("itemBarCodeList", substring);
                confirmList.add(confirmMap);
                status = 2;
            }

            // 获取载具所在库位信息
            StoreLocalDao storeLocal = storeLocalService
                    .findData(new StoreLocalDao().setContainerCode(containerCode));

            String floor = storeLocal.getFloor();
            String goodType = "";
            if (floor.equals(ConstantStatus.M1_FLOOR)) {
                goodType = ConstantStatus.SORTING_AREA;
            }
            if (floor.equals(ConstantStatus.M2_FLOOR)) {
                goodType = ConstantStatus.PICKING_AREA;
            }

            // 全部冻结
            if (materialList.size() == materialDaoList.size()) {
                // 更新物料状态
                for (MaterialDao materialDao : materialDaoList) {
                    materialDao.setDisable(ConstantStatus.FREEZE);
                    materialDao.setDisableDes(freezeVo.getDisableDes());
                    materialDao.setDisableNotes(freezeVo.getDisableNotes());
                    materialDao.setDisableDate(freezeDate);
                    materialService.updateDataByCode(materialDao);
                }
                // 插入冻结物料信息
                List<FreezeTaskRecordDao> freezeTaskRecordList = new ArrayList<>();
                for (MaterialDao materialDao : materialDaoList) {
                    FreezeTaskRecordDao freezeTaskRecordDao = new FreezeTaskRecordDao()
                            .setId(String.valueOf(SnowIdUtil.nextId()))
                            .setTaskId(taskId)
                            .setFloor(floor)
                            .setFreezeTime(freezeDate)
                            .setFreezeName(freezeName)
                            .setDisable(ConstantStatus.FREEZE)
                            .setFreezeDes(disableDes)
                            .setFreezeNotes(disableNotes);
                    BeanUtil.copyProperties(materialDao, freezeTaskRecordDao, CopyOptions.create().setIgnoreNullValue(true));
                    freezeTaskRecordList.add(freezeTaskRecordDao);
                }
                freezeTaskRecordService.saveBatchData(freezeTaskRecordList);
                // 同步黑湖冻结单信息
                // MesNetworkRequest.materialFreezeRequest(containerCode, materialList);
                status = 0;
            }

            // 出库到料箱抽检区/出库到栈板分检区
            if (confirm && materialList.size() != entry.getValue().size()
                    && (floor.equals(ConstantStatus.M2_FLOOR)
                    || floor.equals(ConstantStatus.M1_FLOOR))) {

                // 冻结单号
                FreezeDao freezeDao = new FreezeDao();
                // 任务id
                freezeDao.setId(String.valueOf(SnowIdUtil.nextId()));
                freezeDao.setTaskId(taskId);
                freezeDao.setStatus(ConstantStatus.FREEZE_TO_BE);
                // 任务储位查询信息
                freezeDao.setFloor(floor);
                freezeDao.setWorkIp(workIp);
                freezeDao.setGoodType(goodType);
                // 任务开始储位
                String storeId = storeLocal.getId();
                freezeDao.setTaskStart(storeId);
                // storeIdList.add(storeId);
                // 载具编码与状态
                freezeDao.setContainerCode(containerCode);
                freezeDao.setContainerStatus(ConstantStatus.CONTAINER_TO_BE);
                // 任务创建人与时间
                freezeDao.setFreezeTime(freezeDate);
                freezeDao.setFreezeName(freezeName);
                // 冻结描述与备注
                freezeDao.setFreezeDes(disableDes);
                freezeDao.setFreezeNotes(disableNotes);
                // 插入冻结物料信息
                this.save(freezeDao);
                // freezeDaoList.add(freezeDao);
                StoreLocalDao storeLocalDao = new StoreLocalDao()
                        .setId(storeId)
                        .setStatus(InboundStatusEnum.OUTBOUND_LOCK.status);
                storeLocalService.updateData(storeLocalDao);

                // 更新物料状态
                for (MaterialDao materialDao : materialDaoList) {
                    materialDao.setDisable(ConstantStatus.FREEZE);
                    materialDao.setDisableDes(freezeVo.getDisableDes());
                    materialDao.setDisableNotes(freezeVo.getDisableNotes());
                    materialDao.setDisableDate(freezeDate);
                    materialService.updateDataByCode(materialDao);
                    // materialResultList.add(materialDao);
                }
                status = 1;
            }
        }
        if (status == 2) {
            return new Result<>(201, "存在混箱/托需要拆箱/托操作！", confirmList);
        }
//        if (status == 1) {
//            this.startTaskFindFreezeOutBound(taskId);
//            for (MaterialDao materialDao : materialResultList) {
//                materialService.updateByItemBarCode(materialDao);
//            }
//            // 储位锁定
//            storeLocalService.updateStatusByStoreList(storeIdList, InboundStatusEnum.OUTBOUND_LOCK.status);
//            // 开启线程任务分配储位及出库
//            if (floor.equals(ConstantStatus.M2_FLOOR)) {
//                this.startTaskFindFreezeOutBound(taskId);
//            }
//        }
        return Result.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> startTaskFindFreezeOutBound(String taskId) {
        LambdaUpdateWrapper<FreezeDao> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(FreezeDao::getTaskId, taskId);
        wrapper.set(FreezeDao::getStatus, ConstantStatus.FREEZE_IN_PROGRESS);
        boolean update = this.update(wrapper);
        if (update) {
            return Result.success();
        }
        return Result.error("任务单号不存在");
    }

    @Async
    public void scheduledTasksOutBound() {
        FreezeDao freezeDao = new FreezeDao()
                .setStatus(ConstantStatus.FREEZE_IN_PROGRESS)
                .setContainerStatus(ConstantStatus.CONTAINER_TO_BE);
        List<FreezeDao> freezeList = this.findDataList(freezeDao);
        if (freezeList.isEmpty()) {
            return;
        }
        while (!freezeList.isEmpty()) {
            for (FreezeDao freeze : freezeList) {
                // 货位信息
                String goodType = freeze.getGoodType();
                // 楼层信息
                String floor = freeze.getFloor();
                // 工位IP
                String workIp = freeze.getWorkIp();
                // 查询储位信息
                List<String> storeIdList = new ArrayList<>();
                storeOutsideService.findAvailableStoreIdList(
                        ConstantStatus.ANTI_SORTING_RETURN_STATION,
                        workIp, floor, goodType, storeIdList);
                if (storeIdList.isEmpty()) {
                    continue;
                }
                // 修改任务单信息
                String outStoreId = storeIdList.get(0);
                freeze.setTaskEnd(outStoreId);
                freeze.setContainerStatus(ConstantStatus.CONTAINER_OUTBOUND_ING);
                // 更新任务单，库外储位信息
                try {
                    Result<?> result = this.FreezeExecuteTransactional(freeze);
                    if (result.getCode() != 200) {
                        freezeLog.error("{} ", Thread.currentThread().getName());
                    }
                } catch (Exception e) {
                    freezeLog.error("{}   {}", Thread.currentThread().getName(), e.getMessage());
                }
            }
            freezeList = this.findDataList(freezeDao);
        }
    }

    @Override
    public Result<List<MaterialDao>> scanFreezeContainerCode(String containerCode) {
        if (containerCode == null || containerCode.isEmpty()) {
            return Result.error("容器编号不能为空");
        }
        try {
            LambdaQueryWrapper<MaterialDao> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(MaterialDao::getContainerCode, containerCode);
            wrapper.eq(MaterialDao::getDisable, ConstantStatus.FREEZE);
            wrapper.orderByAsc(MaterialDao::getContainerCode);
            return Result.success(materialService.list(wrapper));
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }

    @Override
    public Result<?> rebindItemBarCodeList(AgainBindVo againBindVo) {
        if (againBindVo == null) {
            return Result.error("参数错误");
        }
        String containerCode = againBindVo.getContainerCode();
        List<String> itemBarCodeList = againBindVo.getItemBarCodeList();
        if (containerCode == null || containerCode.isEmpty()) {
            return Result.error("容器编号不能为空");
        }
        if (itemBarCodeList == null || itemBarCodeList.isEmpty()) {
            return Result.error("物料条码不能为空");
        }

        ContainerDao containerDao = containerService.findDataOne(containerCode);
        if (containerDao == null || containerDao.getLocal().equals(ConstantStatus.InsideTheWarehouse)) {
            return Result.error("容器编号不存在或者载具位置在库内");
        }

        // 判断扫描物料是否存在不冻结的物料条码
        List<MaterialDao> codeList = materialService.findDataList(itemBarCodeList);
        for (MaterialDao materialDao : codeList) {
            if (materialDao.getDisable() == null || materialDao.getDisable() == 0) {
                return Result.error("存在未冻结物料！");
            }
        }

        MaterialDao materialDao = new MaterialDao().setContainerCode(containerCode);
        boolean updateResult = materialService.updateDataByList(itemBarCodeList, materialDao);
        if (updateResult) {
            // 根据载具编码获取要物料信息
            List<MaterialDao> materialList = materialService
                    .findDataDao(new MaterialDao().setContainerCode(containerCode));
            return Result.success(materialList);
        }
        return Result.error();
    }


    @Override
    public Result<Map<String, Integer>> countFreezeContainerCode(String taskId) {
        Map<String, Integer> sortingMap = new HashMap<>();
        sortingMap.put("sorted", 0);
        sortingMap.put("sorting", 0);
        sortingMap.put("total", 0);
        LambdaQueryWrapper<FreezeDao> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FreezeDao::getTaskId, taskId);
        List<FreezeDao> freezeDaoList = this.list(queryWrapper);
        for (FreezeDao freezeDao : freezeDaoList) {
            Integer containerStatus = freezeDao.getContainerStatus();
            String sorting = Objects.equals(containerStatus, ConstantStatus.CONTAINER_MERGE_COMPLETED) ? "sorted" : "sorting";
            if (sortingMap.containsKey(sorting)) {
                sortingMap.put(sorting, sortingMap.get(sorting) + 1);
            } else {
                sortingMap.put(sorting, 1);
            }
        }
        sortingMap.put("total", freezeDaoList.size());
        return Result.success(sortingMap);
    }


    @Override
    public Result<?> completeFreeze(Map<String, Object> params) {

        if (params.get("containerCode") == null || !(params.get("containerCode") instanceof String)) {
            return Result.error("容器编号不能为空");
        }
        if (params.get("floor") == null || !(params.get("floor") instanceof String)) {
            return Result.error("楼层不能为空");
        }
        if (params.get("freeze") == null || !(params.get("freeze") instanceof Boolean)) {
            return Result.error("是否冻结不能为空");
        }
        String containerCode = (String) params.get("containerCode");
        String floor = (String) params.get("floor");
        // 载具是否为冻结回库载具 true是冻结载具，false不是
        Boolean freeze = (Boolean) params.get("freeze");
        // 根据载具编码获取要物料信息
        List<MaterialDao> materialList = materialService
                .findDataDao(new MaterialDao().setContainerCode(containerCode));
        if (materialList == null) {
            return Result.error("未查询到物料信息");
        }
        MesMaterialVo mesMaterialVo = new MesMaterialVo()
                .setData(materialList)
                .setContainerCode(containerCode)
                .setNest(true)
                .setFloor(floor);

        try {
            return this.FreezeInExecuteTransactional(mesMaterialVo, materialList, containerCode, freeze);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> unFreeze(FreezeVo freezeVo) {
        if (freezeVo.getItemBarCodeList().isEmpty()) {
            return Result.error("物料条码不能为空");
        }
        if (freezeVo.getFreezeName() == null) {
            return Result.error("解冻人不能为空");
        }
        List<String> itemBarCodeList = freezeVo.getItemBarCodeList();
        String freezeName = freezeVo.getFreezeName();
        List<MaterialDao> materialList = materialService.findDataList(itemBarCodeList);
        // 判断是否存在未冻结物料
        for (MaterialDao materialDao : materialList) {
            if (materialDao.getDisable().equals(ConstantStatus.NORMAL)) {
                return Result.error("存在未冻结物料！");
            }
        }

        // 获取每个载具对应的物料信息
        Map<String, List<MaterialDao>> freezeMap = new HashMap<>();
        String containerCode = null;
        handleMaterialList(materialList, freezeMap);
        for (Map.Entry<String, List<MaterialDao>> entry : freezeMap.entrySet()) {
            // 获取载具上对应的物料信息表
            containerCode = entry.getKey();
            // 根据载具编码获取要物料信息
            List<MaterialDao> materialDaoList = materialService
                    .findDataDao(new MaterialDao().setContainerCode(containerCode));
            if (entry.getValue().size() != materialDaoList.size()) {
                return Result.error("未选中物料所有信息！");
            }
        }
        if (containerCode == null) {
            return Result.error("未选中物料没有载具信息！");
        }
        // 解冻物料单
        freezeTaskRecordService.updateRecordByItemBarCodeList(itemBarCodeList, freezeName);
        MaterialDao materialDao = new MaterialDao().setDisable(ConstantStatus.NORMAL);
        boolean result = materialService.updateDataByList(itemBarCodeList, materialDao);
        // 同步黑湖物料解冻
        // MesNetworkRequest.materialUnfreezeReQuest(containerCode, itemBarCodeList);
        if (!result) {
            return Result.error("解冻失败");
        }
        return Result.success();
    }


    @Override
    public Result<?> findExistTask() {
        LambdaQueryWrapper<FreezeDao> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(FreezeDao::getTaskId, FreezeDao::getStatus);
        wrapper.groupBy(FreezeDao::getTaskId).groupBy(FreezeDao::getStatus);
        List<FreezeDao> freezeDaoList = baseMapper.selectList(wrapper);
        boolean flag = false;
        for (FreezeDao freezeDao : freezeDaoList) {
            if (freezeDao.getStatus() == null) {
                continue;
            }
            if (!freezeDao.getStatus().equals(ConstantStatus.FREEZE_COMPLETED)) {
                flag = true;
                break;
            }
        }
        return Result.success(flag);
    }

    /**
     * 冻结物料条码分类，每个不同的载具
     *
     * @param materialList 物料列表
     * @param freezeMap    冻结物料条码分类，每个不同的载具
     */

    public void handleMaterialList(List<MaterialDao> materialList, Map<String, List<MaterialDao>> freezeMap) {
        for (MaterialDao materialDao : materialList) {
            String containerCode = materialDao.getContainerCode();
            if (freezeMap.containsKey(containerCode)) {
                freezeMap.get(containerCode).add(materialDao);
            } else {
                List<MaterialDao> freeList = new ArrayList<>();
                freeList.add(materialDao);
                freezeMap.put(containerCode, freeList);
            }
        }
    }


    /**
     * 冻结更新信息-调用WCS出库
     *
     * @param freeDao 冻结任务单
     */
    public Result<?> FreezeExecuteTransactional(FreezeDao freeDao) {
        // 创建出库AGV对象
        // 接口调用失败，标记事务回滚
        return transactionTemplate.execute(status -> {
            try {
                FreezeService freezeService = SpringBeanHolder.getBean(FreezeService.class);

                String outStoreId = freeDao.getTaskEnd();
                String goodType = freeDao.getGoodType();
                String containerCode = freeDao.getContainerCode();

                if (outStoreId == null || goodType == null || containerCode == null ) {
                    return Result.error();
                }

                // 修改目的储位状态
                StoreOutsideDao storeOutsideDao = new StoreOutsideDao()
                        .setId(outStoreId)
                        .setStatus(InboundStatusEnum.INBOUND_LOCK.status);
                storeOutsideService.updateData(storeOutsideDao);

                // 载具申请储位成功（锁定状态）
                ContainerDao containerDao = new ContainerDao()
                        .setId(containerCode)
                        .setIonLock(ConstantStatus.CONTAINER_LOCKED);
                containerService.updateDataById(containerDao);

                // 修改冻结任务单信息
                freezeService.updateDataByCode(freeDao);

                // 调用WCS出库
                Result<?> result = WcsNetworkRequest.freezeDeliveryTask(freeDao);
                if (result.getCode() != 200) {
                    throw new RuntimeException(result.getMessage());
                }
                return Result.success();
            } catch (Exception e) {
                // 接口调用失败，标记事务回滚
                status.setRollbackOnly();
                return Result.error(e.getMessage());
            }
        });
    }

    /**
     * 冻结更新信息-调用WCS回库
     *
     * @param mesMaterialVo 冻结记录数据
     */
    public Result<?> FreezeInExecuteTransactional(MesMaterialVo mesMaterialVo,
                                                  List<MaterialDao> materialDaoList,
                                                  String containerCode, Boolean isFreeze) {
        // 创建出库AGV对象
        // 接口调用失败，标记事务回滚
        return transactionTemplate.execute(status -> {
            try {
                FreezeTaskRecordService freezeTaskRecordService = SpringContextUtil.getBean(FreezeTaskRecordService.class);
                FreezeService freezeService = SpringContextUtil.getBean(FreezeService.class);
                MaterialService materialService = SpringContextUtil.getBean(MaterialService.class);
                InboundService inboundService = SpringContextUtil.getBean(InboundService.class);


                // 获取回库储位编码
                Result<String> applyStore = inboundService.InboundStorageApply(mesMaterialVo);
                if (applyStore.getCode() != 200) {
                    throw new RuntimeException(applyStore.getMessage());
                }

                // 重新赋值冻结单信息
                FreezeDao freezeDao = freezeService.findDataByCode(containerCode);
                freezeDao.setTaskStart(freezeDao.getTaskEnd());
                freezeDao.setTaskEnd(applyStore.getData());
                freezeDao.setContainerStatus(ConstantStatus.CONTAINER_MERGE_COMPLETED);

                String taskId = freezeDao.getTaskId();
                String taskStart = freezeDao.getTaskStart();
                String taskEnd = freezeDao.getTaskEnd();
                String floor = freezeDao.getFloor();


                // 获取物料编码
                String materialCodeListStr = materialService.getMaterialCodeListStrByContainerCode(containerCode);
                // 创建出库AGV对象
                OutBoundTaskToWcsVo task = new OutBoundTaskToWcsVo()
                        .setWmsTaskId(taskId)
                        .setContainerCode(containerCode)
                        .setSource(taskStart)
                        .setDestination(taskEnd)
                        .setPriority(PriorityEnum.MEDIUM.getWeight())
                        .setFloor(floor)
                        .setDeliveryType(ConstantStatus.Return_Delivery_Type)
                        .setTaskType(ConstantStatus.Freeze_RetBound_Type)
                        .setMaterIalCode(materialCodeListStr);
                ;
                if (isFreeze) {
                    // 冻结回库
                    // 创建冻结记录对象
                    List<FreezeTaskRecordDao> freezeTaskRecordList = new ArrayList<>();
                    for (MaterialDao materialDao : materialDaoList) {
                        FreezeTaskRecordDao freezeTaskRecordDao = new FreezeTaskRecordDao();
                        freezeTaskRecordDao.setId(String.valueOf(SnowIdUtil.nextId()));
                        BeanUtil.copyProperties(materialDao, freezeTaskRecordDao, CopyOptions.create().setIgnoreNullValue(true));
                        BeanUtil.copyProperties(freezeDao, freezeTaskRecordDao, CopyOptions.create().setIgnoreNullValue(true));
                        freezeTaskRecordList.add(freezeTaskRecordDao);
                    }
                    // 插入数据到冻结记录表中
                    freezeTaskRecordService.saveBatch(freezeTaskRecordList);
                }
                // 更新任务单信息
                freezeService.updateDataByCode(freezeDao);

                // 判断任务单载具是否全部完成
                List<FreezeDao> freezeDaoList = freezeService.findDataList(new FreezeDao().setTaskId(taskId));
                boolean isCompleted = true;
                for (FreezeDao dao : freezeDaoList) {
                    if (!dao.getContainerStatus().equals(ConstantStatus.CONTAINER_MERGE_COMPLETED)) {
                        isCompleted = false;
                        break;
                    }
                }
                if (isCompleted) {
                    LambdaUpdateWrapper<FreezeDao> wrapper = new LambdaUpdateWrapper<>();
                    wrapper.eq(FreezeDao::getTaskId, taskId);
                    wrapper.set(FreezeDao::getStatus, ConstantStatus.FREEZE_COMPLETED);
                    boolean update = freezeService.update(wrapper);
                    if (!update) {
                        throw new RuntimeException("更新任务单状态失败");
                    }
                }
                // 调用WCS接口
                Result<?> result = WcsNetworkRequest.deliveryTask(task);
                if (result.getCode() != 200) {
                    throw new RuntimeException(result.getMessage());
                }
                return Result.success();
            } catch (Exception e) {
                // 接口调用失败，标记事务回滚
                status.setRollbackOnly();
                throw e;
            }
        });
    }


}
